
using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Data;
using Nop.Core.Domain.XJ;
using Nop.Services.Events;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Nop.Services.XJ
{
	/// <summary>
	/// XJPlace service
	/// </summary>
	public partial class XJPlaceService : IXJPlaceService
	{
		#region Constants

		/// <summary>
		/// Key for caching
		/// </summary>
		private const string XJPLACES_ALL_KEY = "Nop.xjplace.all";
		/// <summary>
		/// Key for caching
		/// </summary>
		/// <remarks>
		/// {0} : xJPlace ID
		/// </remarks>
		private const string XJPLACE_BY_ID_KEY = "Nop.xjplace.id-{0}";
		/// <summary>
		/// Key pattern to clear cache
		/// </summary>
		private const string XJPLACES_PATTERN_KEY = "Nop.xjplace.";
		#endregion

		#region Fields
		private readonly IRepository<XJPlace> _xJPlaceRepository;
		private readonly IEventPublisher _eventPublisher;
		private readonly ICacheManager _cacheManager;
		#endregion

		#region Ctor

		/// <summary>
		/// Ctor
		/// </summary>
		/// <param name="cacheManager">Cache manager</param>
		/// <param name="xJPlaceRepository">XJPlace repository</param>
		/// <param name="eventPublisher">Event published</param>
		public XJPlaceService(ICacheManager cacheManager,
			IRepository<XJPlace> xJPlaceRepository,
			IEventPublisher eventPublisher)
		{
			this._cacheManager = cacheManager;
			this._xJPlaceRepository = xJPlaceRepository;
			this._eventPublisher = eventPublisher;
		}

		#endregion

		#region Methods

		/// <summary>
		/// Gets all XJPlaces
		/// </summary>
		/// <returns>XJPlaces</returns>
		public virtual IList<XJPlace> GetAllXJPlaces()
		{
			string key = XJPLACES_ALL_KEY;
			return _cacheManager.Get(key, () =>
			{
				var query = from a in _xJPlaceRepository.Table
							where !a.Deleted
							&& a.Published
							orderby a.DisplayOrder ascending, a.Name ascending
							select a;
				return query.ToList();
			});
		}

		public virtual IPagedList<XJPlace> GetAllPlaces(string name = "", bool showHidden = true, int pageIndex = 0, int pageSize = int.MaxValue)
		{
			var query = _xJPlaceRepository.Table;
			if (!showHidden)
				query = query.Where(c => c.Published);
			if (!String.IsNullOrWhiteSpace(name))
				query = query.Where(c => c.Name.Contains(name));
			query = query.Where(c => !c.Deleted);
			query = query.OrderBy(c => c.DisplayOrder).ThenBy(c => c.Name);

			//paging
			return new PagedList<XJPlace>(query, pageIndex, pageSize);
		}

		public virtual IList<XJPlace> GetPlacesByIds(int[] placeIds)
		{
			if (placeIds == null || placeIds.Length == 0)
				return new List<XJPlace>();

			var query = from c in _xJPlaceRepository.Table
						where placeIds.Contains(c.Id) && !c.Deleted
						select c;
			return query.ToList();
		}

		/// <summary>
		/// Gets a XJPlace 
		/// </summary>
		/// <param name="xJPlaceId">XJPlace identifier</param>
		/// <returns>XJPlace</returns>
		public virtual XJPlace GetXJPlaceById(int xJPlaceId)
		{
			if (xJPlaceId == 0)
				return null;

			string key = string.Format(XJPLACE_BY_ID_KEY, xJPlaceId);
			return _cacheManager.Get(key, () => _xJPlaceRepository.GetById(xJPlaceId));
		}

		public virtual string GetNameById(int id)
		{
			var query = GetXJPlaceById(id);
			return query == null ? "" : query.Name;
		}

		/// <summary>
		/// Inserts a XJPlace
		/// </summary>
		/// <param name="xJPlace">XJPlace</param>
		public virtual void InsertXJPlace(XJPlace xJPlace)
		{
			if (xJPlace == null)
				throw new ArgumentNullException("xJPlace");

			_xJPlaceRepository.Insert(xJPlace);

			_cacheManager.RemoveByPattern(XJPLACES_PATTERN_KEY);

			//event notification
			_eventPublisher.EntityInserted(xJPlace);
		}

		/// <summary>
		/// Updates the XJPlace
		/// </summary>
		/// <param name="xJPlace">XJPlace</param>
		public virtual void UpdateXJPlace(XJPlace xJPlace)
		{
			if (xJPlace == null)
				throw new ArgumentNullException("xJPlace");

			_xJPlaceRepository.Update(xJPlace);

			_cacheManager.RemoveByPattern(XJPLACES_PATTERN_KEY);

			//event notification
			_eventPublisher.EntityUpdated(xJPlace);
		}

		/// <summary>
		/// Deletes a XJPlace
		/// </summary>
		/// <param name="xJPlace">XJPlace</param>
		public virtual void DeleteXJPlace(XJPlace xJPlace)
		{
			if (xJPlace == null)
				throw new ArgumentNullException("xJPlace");

			_xJPlaceRepository.Delete(xJPlace);

			_cacheManager.RemoveByPattern(XJPLACES_PATTERN_KEY);

			//event notification
			_eventPublisher.EntityDeleted(xJPlace);
		}

		public virtual void DeletePlace(XJPlace xJPlace)
		{
			if (xJPlace == null)
				throw new ArgumentNullException("xJPlace");

			xJPlace.Deleted = true;
			UpdateXJPlace(xJPlace);

			//event notification
			_eventPublisher.EntityDeleted(xJPlace);
		}

		#endregion
	}
}
